home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 May / EnigmA AMIGA RUN 18 (1997)(G.R. Edizioni)(IT)[!][issue 1997-05][EAR-CD II].iso / softwareupdate / system / amigados / files / example5.c < prev    next >
C/C++ Source or Header  |  1996-10-10  |  14KB  |  453 lines

  1. /***********************************************************/
  2. /*                                                         */
  3. /* Amiga C Encyclopedia (ACE)           Amiga C Club (ACC) */
  4. /* --------------------------           ------------------ */
  5. /*                                                         */
  6. /* Manual:  AmigaDOS                    Amiga C Club       */
  7. /* Chapter: Files                       Tulevagen 22       */
  8. /* File:    Example5.c                  181 41  LIDINGO    */
  9. /* Author:  Anders Bjerin               SWEDEN             */
  10. /* Date:    93-03-13                                       */
  11. /* Version: 1.2                                            */
  12. /*                                                         */
  13. /*   Copyright 1993, Anders Bjerin - Amiga C Club (ACC)    */
  14. /*                                                         */
  15. /* Registered members may use this program freely in their */
  16. /*     own commercial/noncommercial programs/articles.     */
  17. /*                                                         */
  18. /***********************************************************/
  19.  
  20. /* This example demonstrates how you can write a (very) simple */
  21. /* data base program. In this data base you can add names of   */
  22. /* persons and their telephone numbers. Whenever you want you  */
  23. /* can display the complete user list.                         */
  24. /*                                                             */
  25. /* This example uses a "Console" window which has not been     */
  26. /* explained yet. It is therefore a bit difficult, and if you  */
  27. /* are unfamiliar with AmigaDOS you should skip this example   */
  28. /* for the moment and look at it later.                        */
  29.  
  30.  
  31.  
  32. /* In this example we are using a "Console window" in which we  */
  33. /* do the conversation with the user. Please note that I have   */
  34. /* not described Console windows yet (you can read abut it in   */
  35. /* chapter 6 "Handlers") so you should simply skip all parts    */
  36. /* which has to do with the Console.                            */
  37. /*                                                              */
  38. /* In the example we use two special functions, "print_text()", */
  39. /* and "collect_text()". They use the Console window and are    */
  40. /* similar to the normal "printf()" and "scanf()" routines. The */
  41. /* reason why I use a Console window rather than using the      */
  42. /* printf() and scanf() functions directly is because these     */
  43. /* normal C functions, printf() and scanf(),are not very        */
  44. /* practical (and you usually ends up with a lot of buffered    */
  45. /* signs which are tricky to avoid). The Console is therefore   */
  46. /* much easier to work with and looks better.                   */
  47. /*                                                              */
  48. /* When you later read about the "handlers" and "Console"       */
  49. /* windows you can take a look on this example again. It is a   */
  50. /* rather good demonstration on how to use Console windows.     */
  51.  
  52.  
  53.  
  54. /* Include the dos library definitions: */
  55. #include <dos/dos.h>
  56.  
  57. /* Now we include the necessary function prototype files:         */
  58. #include <clib/dos_protos.h>       /* General dos functions...    */
  59. #include <clib/exec_protos.h>      /* System functions...         */
  60. #include <stdio.h>                 /* Std functions [printf()...] */
  61. #include <stdlib.h>                /* Std functions [exit()...]   */
  62. #include <string.h>                /* Std functions [strlen()...] */
  63.  
  64.  
  65.  
  66. /* The maximum length of the strings: */
  67. #define MAX_MENU_LENGTH  10
  68. #define MAX_NAME_LENGTH  50
  69. #define MAX_PHONE_LENGTH 20
  70.  
  71.  
  72.  
  73. /* Set name and version number: */
  74. UBYTE *version = "$VER: AmigaDOS/InputOutput/Example5 1.2";
  75.  
  76.  
  77.  
  78. /* The information will be stored in this type of structure: */
  79. struct person
  80. {
  81.   UBYTE name[ MAX_NAME_LENGTH ];
  82.   UBYTE phone[ MAX_PHONE_LENGTH ];
  83. };
  84.  
  85. /* In this example we will use the "person" structure to    */
  86. /* store information about a user in. The structure will be */
  87. /* saved in a file so we later can retreive the information */
  88. /* when we want to list all users. When I refer to this     */
  89. /* structure I will call it a "record".                     */
  90.  
  91.  
  92.  
  93. /* Declared our own functions: */
  94.  
  95. /* Our main function: */
  96. int main( int argc, char *argv[] );
  97.  
  98. /* Adds a person to the user list: */
  99. BOOL add_person( BPTR my_file, BPTR my_console );
  100.  
  101. /* Displays the complete user list: */
  102. BOOL show_userlist( BPTR my_file, BPTR my_console );
  103.  
  104. /* Prints a string in a file (in our example a Console window): */
  105. int print_text( BPTR file, STRPTR text );
  106.  
  107. /* Collects input from a file (in our example a Console window): */
  108. int collect_text( BPTR file, STRPTR text, int max_length );
  109.  
  110.  
  111.  
  112. /* Main function: */
  113.  
  114. int main( int argc, char *argv[] )
  115. {
  116.   /* A "BCPL" pointer to our file: */
  117.   BPTR my_userfile;
  118.  
  119.   /* A "BCPL" pointer to our "Console" window: */
  120.   BPTR my_console;
  121.  
  122.   /* Boolean value to see if we should */
  123.   /* stay in the main loop or not:     */
  124.   BOOL work;
  125.  
  126.   /* Store here what the user type in: */
  127.   UBYTE user_input[ MAX_MENU_LENGTH ];
  128.  
  129.   /* What menu option the user selected: */
  130.   int menu_option;
  131.  
  132.  
  133.  
  134.   /* First we will open a "Console window" in which we */
  135.   /* can do all the conversation with user:            */
  136.   my_console = 
  137.     Open( "CON:0/0/400/200/SUPERBASE 5", MODE_NEWFILE );
  138.   
  139.   /* Could we open the Console window? */
  140.   if( !my_console )
  141.   {
  142.     /* Inform the user: */
  143.     printf( "Error! Could not open the Console window!\n" );
  144.  
  145.     /* Exit with an error code: */
  146.     exit( 20 );
  147.   }
  148.  
  149.  
  150.  
  151.   /* Open the user file: (If the file exists it will be opened as an */
  152.   /* old file, and if the file does not exist it will be created.)   */
  153.   my_userfile = Open( "RAM:UserList.dat", MODE_READWRITE );
  154.   
  155.   /* Have we opened the file successfully? */
  156.   if( !my_userfile )
  157.   {
  158.     /* Inform the user: */
  159.     printf( "Error! Could not open the file!\n" );
  160.  
  161.     /* Close the Console window: */
  162.     Close( my_console );
  163.  
  164.     /* Exit with an error code: */
  165.     exit( 21 );
  166.   }
  167.  
  168.  
  169.   
  170.   /* Run at least one time in while loop: */
  171.   work = TRUE;
  172.  
  173.   /* Stay in the while loop as long as the user want to continue: */
  174.   while( work )
  175.   {
  176.     /* Print the menu: */
  177.     print_text( my_console,
  178.       "\nMenu:\n1. Add new person\n2. Show all persons\n9. Quit\n=> " );
  179.  
  180.     /* Collect menu option: */
  181.     collect_text( my_console, user_input, MAX_MENU_LENGTH );
  182.  
  183.     /* Convert the string into a number: */
  184.     menu_option = atoi( user_input );
  185.  
  186.     /* Execute the option: */
  187.     switch( menu_option )
  188.     {
  189.       case 9: work = FALSE; break;
  190.       case 1: add_person( my_userfile, my_console ); break;
  191.       case 2: show_userlist( my_userfile, my_console ); break;
  192.       default: print_text( my_console,
  193.                "Select one of the options 1, 2 or 9!\n" );
  194.     }
  195.   }
  196.  
  197.  
  198.  
  199.   /* Close the file: */
  200.   Close( my_userfile );
  201.  
  202.   /* Close the Console window: */
  203.   Close( my_console );
  204.  
  205.  
  206.  
  207.   /* Some final messages... */
  208.   printf( "Thank you for using SUPERBASE 5!\n" );
  209.   printf( "The userlist has been saved so you can\n" );
  210.   printf( "continue to add information later on...\n" );
  211.   
  212.   /* The End! */
  213.   exit( 0 );
  214. }
  215.  
  216.  
  217.  
  218. /* Asks the user to enter some information about a person.  */
  219. /* The information will then be added at the end of the     */
  220. /* user file. Returns FALSE if the data could not be saved, */
  221. /* else TRUE is returned.                                   */
  222.  
  223. BOOL add_person
  224. (
  225.   BPTR my_file,
  226.   BPTR my_console
  227. )
  228. {
  229.   /* Declare a person structure: */
  230.   struct person new;
  231.  
  232.   /* Store here the number of bytes actually written: */
  233.   long bytes_written;
  234.   
  235.  
  236.  
  237.   /* Info to the user: */  
  238.   print_text( my_console, "Add new person!\n" );
  239.  
  240.   /* Name: (An empty string is not accepted) */
  241.   new.name[ 0 ] = NULL;
  242.   while( new.name[ 0 ] == NULL )
  243.   {
  244.     print_text( my_console, "Name: " );
  245.     collect_text( my_console, new.name, MAX_NAME_LENGTH );
  246.   }
  247.   
  248.   /* Phone: (An empty string is not accepted) */
  249.   new.phone[ 0 ] = NULL;
  250.   while( new.phone[ 0 ] == NULL )
  251.   {
  252.     print_text( my_console, "Phone: " );
  253.     collect_text( my_console, new.phone, MAX_PHONE_LENGTH );
  254.   }
  255.   
  256.  
  257.  
  258.   /* Move the file cursor to the end of the file:  */
  259.   /* (We have to make sure that the file cursor is */
  260.   /* standing at the endo of the file so nothing   */
  261.   /* will be overwritten when we save the info.)   */
  262.   Seek( my_file, 0, OFFSET_END );
  263.  
  264.  
  265.  
  266.   /* Store the information about the person: ("new" is the structure */
  267.   /* we want to save, and since the function needs a pointer to the  */
  268.   /* memory that should be saved we put a "&" sign in front of the   */
  269.   /* structure name. The size of the structure can easily be         */
  270.   /* calculated with help of the "sizeof()" function.)               */
  271.   bytes_written = Write( my_file, &new, sizeof( struct person ) );
  272.  
  273.   /* Could we save all data? */ 
  274.   if( bytes_written != sizeof( struct person ) )
  275.   {
  276.     /* No! The number of bytes actually written */
  277.     /* was less than what we wanted to write!   */
  278.     print_text( my_console, "Error! Could not save the data!\n" );
  279.  
  280.     /* Well, there is not much we can do about it now, */
  281.     /* we return an error message, but that is all.    */
  282.     return( FALSE );
  283.   }
  284.   else
  285.   {
  286.     /* Yes, all bytes were successfully saved! */
  287.     print_text( my_console, "Person added to the userlist!\n" );
  288.   }
  289.  
  290.  
  291.  
  292.   /* OK! */
  293.   return( TRUE );
  294. }
  295.  
  296.  
  297.  
  298. /* Displays the complete user list. Returns TRUE if all users */
  299. /* were successfully listed, else FALSE is returned.          */
  300.  
  301. BOOL show_userlist
  302. (
  303.   BPTR my_file,
  304.   BPTR my_console
  305. )
  306. {
  307.   /* Declare a person structure: */
  308.   struct person current_person;
  309.  
  310.   /* Store here the number of bytes actually collected: */
  311.   long bytes_read;
  312.  
  313.   
  314.  
  315.  
  316.   /* Move the file cursor to the beginning of the file: */
  317.   /* (We want to read all records in this file, and     */
  318.   /* consequently we have to move to the first record   */
  319.   /* in the file.)                                      */
  320.   Seek( my_file, 0, OFFSET_BEGINNING );
  321.  
  322.  
  323.   /* Stay in the loop until we return to the main function: */
  324.   while( TRUE )
  325.   {
  326.     /* Collect a record: */
  327.     bytes_read = Read( my_file, ¤t_person, sizeof( struct person ) );
  328.  
  329.     /* Could we collect enough data to fill a record? */
  330.     if( bytes_read != sizeof( struct person ) )
  331.     {
  332.       /* No, we cold not fill a record! This means that */
  333.       /* we have either reached the end of the file, or */
  334.       /* there was an error. Read() returns 0 when we   */
  335.       /* reach the end of the file, and -1 if there was */
  336.       /* an error. (If some data was collected but not  */
  337.       /* all this would be an error in our program      */
  338.       /* since we expect to find complete records, so   */
  339.       /* any value which is non zero means that there   */
  340.       /* was an error.)                                 */
  341.       if( bytes_read == 0 )
  342.       {
  343.         /* We have simpy reached the end of the file! */
  344.  
  345.         /* Inform the user: */
  346.         print_text( my_console, "End of user list!\n" );
  347.  
  348.         /* Return happily: */
  349.         return( TRUE );
  350.       }
  351.       else
  352.       {
  353.         /* Problems! Inform the user: */
  354.         print_text( my_console, "ERROR while reading user record!\n" );
  355.  
  356.         /* Return with an error code: */
  357.         return( FALSE );
  358.       }
  359.     }
  360.   
  361.     /* Print the information about the user: */
  362.     print_text( my_console, "Name: " );
  363.     print_text( my_console, current_person.name );
  364.  
  365.     print_text( my_console, "\nPhone: " );
  366.     print_text( my_console, current_person.phone );
  367.     print_text( my_console, "\n\n" );
  368.   }
  369. }
  370.  
  371.  
  372.  
  373. /********************************************************/
  374. /*  DO NOT BOTHER ABOUT THESE FUNCTIONS LISTED BELOW!!  */
  375. /* THEY WILL BE FULLY EXPLAINED IN CHAPTER 6 "HANDLERS" */
  376. /********************************************************/
  377.  
  378.  
  379.  
  380. /* Writes text to an already opened file, and returns */
  381. /* the number of characters actualy written.          */
  382.  
  383. int print_text
  384. (
  385.   BPTR file,
  386.   STRPTR text
  387. )
  388. {
  389.   /* Store the number of characters (bytes) actualy written here: */
  390.   int characters_written;
  391.  
  392.  
  393.  
  394.   /* Write the text: */
  395.   characters_written = Write( file, text, strlen( text ) );
  396.  
  397.   /* Returns the number of characters actually written: */
  398.   return( TRUE );
  399. }
  400.  
  401.  
  402.  
  403. /* Collects text from an already opened file, and returns */
  404. /* the number of characters collected.                    */
  405.  
  406. int collect_text
  407. (
  408.   BPTR file,
  409.   STRPTR text,
  410.   int max_length
  411. )
  412. {
  413.   /* Store the number of characters (bytes) actualy read here: */
  414.   int characters_read;
  415.  
  416.  
  417.  
  418.   /* Collect some text: */
  419.   characters_read = Read( file, text, max_length );
  420.  
  421.   /* To be able to print the text we need to put a NULL sign   */
  422.   /* at the end of the string. (All strings must end with a    */
  423.   /* NULL sign, otherwise the functions would not know when    */
  424.   /* the string ends.) To get rid of the Enter sign we simply  */
  425.   /* substitute it with a NULL sign:                           */
  426.   
  427.   /* Put the NULL ('\0') sign at the end of the string: */
  428.   if( characters_read > 0 )
  429.   {
  430.     /* Substitute the Enter sign with a NULL sign: */
  431.     text[ characters_read - 1 ] = NULL;
  432.  
  433.     /* We got at least some text: (maybe only an */
  434.     /* Enter sign but that is OK!)               */
  435.     return( TRUE );
  436.   }
  437.   else
  438.   {
  439.     /* Nothing was entered, not even an Enter sign! */
  440.     /* The console window has been closed!          */
  441.     printf( "The console window was closed!\n" );
  442.  
  443.     /* Clear the string: (Set a NULL sign in the begining) */
  444.     text[ characters_read ] = NULL;
  445.  
  446.     /* Since the window was closed we return FALSE:    */
  447.     /* (In this example we ignore any returned values, */
  448.     /* but if you copy this function to your own       */
  449.     /* program you might want to use the returend      */
  450.     /* values.)                                        */
  451.     return( FALSE );
  452.   }
  453. }